import userCenterBaseInfoApi from '@/api/userCenter/userCenterBaseInfoApi'
import userCenterUpdateBaseInfoApi from '@/api/userCenter/userCenterUpdateBaseInfoApi'
import CUserNickName from '@/components/user/CUserNickName'
import CUserPersonalStatement from '@/components/user/CUserPersonalStatement'
import IUserCenterUpdateBaseInfoForm from '@/model/form/userCenter/IUserCenterUpdateBaseInfoForm'
import IResVO from '@/model/vo/common/IResVO'
import IUserBaseInfoVO from '@/model/vo/user/IUserBaseInfoVO'
import { useAppDispatch, useAppSelector } from '@/store'
import { setUserBaseInfo } from '@/store/user/userSlice'
import { execConfirm, ToastError, ToastSuccess } from '@/util/CommonUtil'
import $http from '@/util/http'
import { getPublicDownFileUrl } from '@/util/UrlUtil'
import { randomNickname } from '@/util/UserUtil'
import Validator from '@/util/Validator'
import { IconClose, IconEdit, IconEmoji, IconPlus } from '@douyinfe/semi-icons'
import {
  Avatar,
  Badge,
  Button,
  Card,
  Form,
  Spin,
  Typography,
  Upload,
} from '@douyinfe/semi-ui'
import { FormApi } from '@douyinfe/semi-ui/lib/es/form'
import { FileItem } from '@douyinfe/semi-ui/lib/es/upload'
import { AxiosRequestConfig } from 'axios'
import { Dispatch, SetStateAction, useEffect, useRef, useState } from 'react'

export default function UserBaseInfo() {
  const userBaseInfo = useAppSelector((state) => state.user.userBaseInfo)
  const appDispatch = useAppDispatch()

  const [loading, setLoading] = useState(false) // 表单是否 loading
  const [disabled, setDisabled] = useState(true) // 表单是否禁用
  const [fileLoading, setFileLoading] = useState(false) // 文件上传 loading
  const formApi = useRef<FormApi>()

  // 更新 userBaseInfo
  function doSetUserBaseInfo(userBaseInfo: IUserBaseInfoVO) {
    appDispatch(setUserBaseInfo(userBaseInfo))
  }

  useEffect(() => {
    // 获取用户基本信息
    userCenterBaseInfoApi().then(({ data }) => {
      doSetUserBaseInfo(data.data)
      formApi.current?.setValues(data.data, { isOverride: true })
    })
  }, [])

  return (
    <div className="m-t-20 flex-c ai-c w-500" style={{ marginLeft: 120 }}>
      <div className="flex-center w100">
        <Spin spinning={fileLoading}>
          <Badge
            count={
              userBaseInfo.avatarUrl ? (
                <div title="点击移除头像">
                  <Button
                    theme="borderless"
                    icon={<IconClose className="red" />}
                    onClick={() => {
                      removeAvatarUrlClick(userBaseInfo, doSetUserBaseInfo)
                    }}
                    disabled={fileLoading}
                  ></Button>
                </div>
              ) : null
            }
          >
            <div title="点击上传头像">
              <Upload
                showUploadList={false}
                customRequest={(arg0) => {
                  customRequest(
                    arg0,
                    setFileLoading,
                    userBaseInfo,
                    doSetUserBaseInfo
                  )
                }}
                onChange={(arg0) => {
                  onChange(arg0, setFileLoading)
                }}
                // 备注：如果选择的不是 accept里面的文件类型，则不会进行任何操作
                accept=".png,.jpeg,.jpg"
                maxSize={2048}
                onSizeError={() => ToastError('图片大于 2MB，请重新选择')}
                disabled={fileLoading}
                action=""
              >
                <Avatar
                  size="extra-large"
                  color="light-blue"
                  src={getPublicDownFileUrl(userBaseInfo.avatarUrl)}
                  hoverMask={
                    <div className="mask">
                      <IconPlus size="extra-large" />
                    </div>
                  }
                >
                  {userBaseInfo.nickname?.slice(0, 1).toUpperCase()}
                </Avatar>
              </Upload>
            </div>
          </Badge>
        </Spin>

        <div className="m-l-20 flex-c cursor-def">
          <Typography.Text className="f-20">
            {userBaseInfo.nickname}
          </Typography.Text>
          <Typography.Text type="tertiary" className="f-15 m-t-10 wb-a">
            {userBaseInfo.personalStatement || '暂无个人说明'}
          </Typography.Text>
        </div>
      </div>

      <Card
        className="w100 p-t-b-10 p-l-r-20 m-t-b-30"
        headerStyle={{ padding: 0 }}
        headerLine={false}
        bodyStyle={{ padding: 0 }}
        shadows="always"
      >
        <>
          <div className="flex jc-e w100">
            {disabled && !loading ? (
              <div title="编辑">
                <Button
                  theme="borderless"
                  onClick={() => {
                    setDisabled(false)
                  }}
                  icon={<IconEdit />}
                >
                  编辑
                </Button>
              </div>
            ) : (
              <>
                <Button
                  theme="borderless"
                  onClick={() => {
                    formApi.current?.submitForm()
                  }}
                  className="m-r-10"
                  loading={loading}
                >
                  保存
                </Button>
                <Button
                  theme="borderless"
                  onClick={() => {
                    formApi.current?.reset()
                    setDisabled(true)
                  }}
                >
                  取消
                </Button>
              </>
            )}
          </div>
          <Form
            disabled={disabled}
            className="m-b-10"
            initValues={userBaseInfo}
            getFormApi={(api) => {
              formApi.current = api
            }}
            onSubmit={(form) => {
              if (loading) return
              setDisabled(true)
              setLoading(true)
              const formTemp: IUserCenterUpdateBaseInfoForm = {
                nickname: form.nickname,
                personalStatement: form.personalStatement,
                avatarUrl: userBaseInfo.avatarUrl,
              }
              userCenterUpdateBaseInfoApi(formTemp)
                .then(({ data }) => {
                  const newUserInfo: IUserBaseInfoVO = {
                    ...userBaseInfo,
                    ...formTemp,
                  }
                  doSetUserBaseInfo(newUserInfo)
                  ToastSuccess(data.msg)
                  setLoading(false)
                })
                .catch(() => {
                  setDisabled(false)
                  setLoading(false)
                })
            }}
          >
            <CUserNickName disabled={disabled}></CUserNickName>
            <CUserPersonalStatement></CUserPersonalStatement>
          </Form>
        </>
      </Card>
    </div>
  )
}

// 自定义上传
function customRequest(
  arg0: {
    fileName: string
    data: Record<string, any>
    file: FileItem
    fileInstance: File
    onProgress: (event: { total: number; loaded: number }) => any
    onError: (
      userXhr: {
        status?: number
      },
      e: Event
    ) => any
    onSuccess: (response: any, e: Event) => any
    withCredentials: boolean
    action: string
  },
  setFileLoading: Dispatch<SetStateAction<boolean>>,
  userBaseInfo: IUserBaseInfoVO,
  doSetUserBaseInfo: (userBaseInfo: IUserBaseInfoVO) => void
) {
  const formData = new FormData()
  formData.append('file', arg0.fileInstance)
  formData.append('bucketName', 'public')
  formData.append('folderName', 'avatar')
  $http
    .post<IResVO, AxiosRequestConfig<IResVO>, FormData>(
      '/file/upload',
      formData,
      { headers: { 'Content-Type': 'multipart/form-data' } }
    )
    .then(async ({ data }) => {
      await updateBaseInfoQuiet({
        avatarUrl: data!.data,
        userBaseInfo,
        doSetUserBaseInfo,
      })
      ToastSuccess('操作成功，如果图片没有及时生效，请等待片刻', 5)
      setFileLoading(false)
    })
    .catch(() => {
      setFileLoading(false)
    })
}

// 静默更新 用户头像信息
function updateBaseInfoQuiet(arg0: {
  avatarUrl: string
  userBaseInfo: IUserBaseInfoVO
  doSetUserBaseInfo: (userBaseInfo: IUserBaseInfoVO) => void
  showToast?: boolean
}) {
  return userCenterUpdateBaseInfoApi({
    avatarUrl: arg0.avatarUrl,
    nickname: arg0.userBaseInfo.nickname,
    personalStatement: arg0.userBaseInfo.personalStatement,
  }).then(({ data }) => {
    arg0.doSetUserBaseInfo({ ...arg0.userBaseInfo, avatarUrl: arg0.avatarUrl })
    if (arg0.showToast) {
      ToastSuccess(data.msg)
    }
  })
}

// 点击移除头像按钮
function removeAvatarUrlClick(
  userBaseInfo: IUserBaseInfoVO,
  doSetUserBaseInfo: (userBaseInfo: IUserBaseInfoVO) => void
) {
  // 静默更新 用户头像信息
  execConfirm(
    () => {
      return updateBaseInfoQuiet({
        avatarUrl: '',
        userBaseInfo,
        doSetUserBaseInfo,
        showToast: true,
      })
    },
    undefined,
    '确定移除头像吗？'
  )
}

// 当选择的文件，发生改变时
function onChange(
  arg0: { fileList: Array<FileItem>; currentFile: FileItem },
  setFileLoading: Dispatch<SetStateAction<boolean>>
) {
  if (arg0.currentFile.status === 'uploading') {
    setFileLoading(true)
  }
  if (arg0.currentFile.status === 'validateFail') {
    setFileLoading(false)
  }
  if (arg0.currentFile.status === 'uploadFail') {
    ToastError('请求错误，请联系管理员')
    setFileLoading(false)
  }
}
